package com.meilai.project.service.personnel.org.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.meilai.project.dto.personnel.org.DepartmentDTO;
import com.meilai.project.entity.personnel.org.Department;
import com.meilai.project.entity.system.User;
import com.meilai.project.exception.CommonException;
import com.meilai.project.mapper.personnel.org.DepartmentMapper;
import com.meilai.project.mapper.system.UserDepartmentRelationMapper;
import com.meilai.project.mapper.system.UserMapper;
import com.meilai.project.service.personnel.org.DepartmentService;
import com.meilai.project.service.system.UserDepartmentRelationService;
import com.meilai.project.service.system.UserService;
import com.meilai.project.util.TreeUtil;
import com.meilai.project.vo.personnel.org.DepartmentWithJobVO;
import com.meilai.project.vo.personnel.org.WebDepartmentListVO;
import com.meilai.project.vo.system.*;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author yxg
 * @date 2020/2/19 20:19
 */
@Service
@Log4j2
public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Department> implements DepartmentService {
    @Autowired
    private UserService userService;
    @Autowired
    private UserDepartmentRelationService userDepartmentRelationService;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserDepartmentRelationMapper userDepartmentRelationMapper;
    @Autowired
    private DepartmentMapper departmentMapper;

    @Override
    public List<Department> select2TopById(long id) {
        List<Department> list = new ArrayList<>();
        selectTree(id, list);
        return list;
    }

    private void selectTree(long id, List<Department> list) {
        Department department = departmentMapper.selectById(id);
        list.add(department);
        if (department.getPid() != null && department.getPid() != 0) {
            selectTree(department.getPid(), list);
        }
    }

    @Override
    public List<WebDepartmentVO> selectPageList(String name, Integer status) {
        List<WebDepartmentVO> returnList = new ArrayList<>();

        QueryWrapper<Department> qw = new QueryWrapper<Department>();
        qw.isNull("deleted_at");
        if (StringUtils.isNotEmpty(name)) qw.like("name", name);
        if (status != null) qw.eq("status", status);
        qw.or(i -> i.eq("pid", 0L));
        List<Department> departments = list(qw);
        if (CollectionUtils.isEmpty(departments)) return returnList;

        //分组
        Map<Long, List<WebDepartmentVO>> collect = departments.stream().map(item -> {
            WebDepartmentVO vo = new WebDepartmentVO();
            BeanUtils.copyProperties(item, vo);
            return vo;
        }).collect(Collectors.groupingBy(WebDepartmentVO::getPid));

        // pid=0的顶级
        returnList.addAll(collect.get(0L));
        returnList.forEach(root -> {
            TreeUtil.TreeForEachUseSort(collect, root);
        });

        return returnList;
    }

    @Override
    @Transactional
    public Boolean addOne(DepartmentDTO dto) {
        Department temp = new Department();
        BeanUtils.copyProperties(dto, temp);
        boolean flag = save(temp);
        if (dto.getPid() == 0) {
            Department dep = new Department();
            dep.setId(temp.getId());
            dep.setRid(temp.getId());
            flag = flag && updateById(dep);
        }
        return flag;
    }

    @Override
    @Transactional
    public Boolean editOne(DepartmentDTO dto) {
        if (dto.getId() == null) return false;
        Department temp = getById(dto.getId());
        if (temp == null) return false;
        Department _temp = new Department();
        BeanUtils.copyProperties(dto, _temp);
        return updateById(_temp);
    }

    @Override
    @Transactional
    public Boolean del(List<Long> ids) {
        Integer count = userDepartmentRelationService.countUserRelationByDepartmentId(ids);
        if (count > 0) throw new CommonException("存在关联用户，无法删除");
        return update(new UpdateWrapper<Department>().set("deleted_at", LocalDateTime.now()).in("id", ids));
    }

    @Override
    @Transactional
    public Boolean changeStatus(Long id, Integer status) {
        Department temp = getById(id);
        if (temp == null) return false;
        Department _temp = new Department();
        _temp.setId(id);
        _temp.setStatus(status);
        return updateById(_temp);
    }

    @Override
    @Transactional
    public Boolean changeAccounting(Long id, boolean accounting) {
        Department temp = getById(id);
        if (temp == null) return false;
        Department _temp = new Department();
        _temp.setId(id);
        _temp.setAccounting(accounting);
        return updateById(_temp);
    }

    @Override
    public List<WebDepartmentForChooseVO> getForChooseList() {
        return baseMapper.getForChooseList();
    }

    @Override
    public List<Long> getChildrenIdsById(Long department_id) {
        return baseMapper.getChildrenIdsById(department_id);
    }

    @Override
    public List<WebDepartmentListVO> getDepartmentsByUserId(Long user_id) {
        return baseMapper.getDepartmentsByUserId(user_id);
    }

    @Override
    @Transactional
    public List<DepartmentWithJobVO> getDepartmentVOs(Long doorId, String tenantName) {
        List<DepartmentWithJobVO> returnList = new ArrayList<>();

        List<User> users = userMapper.selectList(new QueryWrapper<User>().isNull("deleted_at").eq("status", 1).eq("door_id", doorId));
        if (CollectionUtils.isEmpty(users)) return returnList;
        if (users.size() > 1) {
            log.error("查找部门出错，多于一个用户，door_id：{},tenantName：{}", doorId, tenantName);
            throw new CommonException("查询公司列表出错，请联系管理员");
        }

        List<WebUserDepartmentRelationByUserIdVO> departmentVOs = userDepartmentRelationMapper.getActiveVOByUserId(users.get(0).getId());
        if (CollectionUtils.isNotEmpty(departmentVOs)) {
            returnList = departmentVOs.stream().map(item -> {
                DepartmentWithJobVO vo = new DepartmentWithJobVO();
                BeanUtils.copyProperties(item, vo);
                return vo;
            }).collect(Collectors.toList());
        }

        return returnList;
    }

    @Override
    public List<Department> getCompany() {
        return this.list(Wrappers.<Department>lambdaQuery().eq(Department::getAccounting, 1).ne(Department::getId, 1).isNull(Department::getDeleted_at));
    }

    @Override
    public String getDeptCompleteNameById(Long id) {
        String fullName = baseMapper.getDepFullNameById(id);
        return fullName.substring(fullName.indexOf("/") + 1);
    }
}
